package com.learn.util;

/**
 * Bytes & ValueTyte Convert
 */
public class ByteUtil {
    /**
     * int convert to 4bytes<br>
     * small end mode
     * 
     * @param value
     * @return
     */
    public static byte[] intToBytes(int value) {
        return intToBytes(value, 4);
    }

    /**
     * int convert to nbytes<br>
     * small end mode<br>
     * use only int greater than equal 0
     * 
     * @param value
     * @return
     */
    public static byte[] intToBytes(int value, int n) {
        if (n > 4 || n <= 0) {
            throw new IllegalArgumentException("parameter n must be less than equal 4 and greater than equal 0.");
        }

        byte[] bytes = new byte[n];

        for (int i = 0; i < n; i++) {
            bytes[i] = (byte) (value >>> (i * 8));
        }

        return bytes;
    }

    /**
     * bytes convert to int<br>
     * small end mode
     * 
     * @param value
     * @return
     */
    public static int bytesToInt(byte[] bytes) {
        if (bytes == null) {
            throw new IllegalArgumentException("parameter bytes must not be null.");
        }
        if (bytes.length > 4) {
            throw new IllegalArgumentException("parameter bytes length must be less than equal 4.");
        }

        int value = 0;

        for (int i = bytes.length - 1; i > -1; i--) {
            value <<= 8;
            value |= (bytes[i] & 0xFF);
        }

        return value;
    }

    /**
     * bytes convert to int<br>
     * small end mode
     * 
     * @param value
     * @return
     */
    public static int bytesToInt(byte[] bytes, int index, int length) {
        if (bytes == null) {
            throw new IllegalArgumentException("parameter bytes must not be null.");
        }
        if (index < 0) {
            throw new IllegalArgumentException("parameter index must be great than equal to 0.");
        }
        if (length < 1) {
            throw new IllegalArgumentException("parameter length must be great than equal to 1.");
        }

        int preIndex = index - 1;
        int endIndex = index + length;
        if (endIndex > bytes.length) {
            throw new IllegalArgumentException("out of range (index + length > bytes.length).");
        }

        int value = 0;

        for (int i = endIndex - 1; i > preIndex; i--) {
            value <<= 8;
            value |= (bytes[i] & 0xFF);
        }

        return value;
    }

    /**
     * long convert to 8bytes<br>
     * small end mode
     * 
     * @param value
     * @return
     */
    public static byte[] longToBytes(long value) {
        int length = 8;
        byte[] bytes = new byte[length];

        for (int i = 0; i < length; i++) {
            bytes[i] = (byte) (value >>> (i * 8));
        }

        return bytes;
    }

    /**
     * bytes convert to long<br>
     * small end mode
     * 
     * @param value
     * @return
     */
    public static long bytesToLong(byte[] bytes) {
        if (bytes == null) {
            throw new IllegalArgumentException("parameter bytes must not be null.");
        }
        if (bytes.length > 8) {
            throw new IllegalArgumentException("parameter bytes length must be less than equal 8.");
        }

        long value = 0;

        for (int i = bytes.length - 1; i > -1; i--) {
            value <<= 8;
            value |= (bytes[i] & 0xFF);
        }

        return value;
    }

    /**
     * bytes convert to long<br>
     * small end mode
     * 
     * @param value
     * @return
     */
    public static long bytesToLong(byte[] bytes, int index, int length) {
        if (bytes == null) {
            throw new IllegalArgumentException("parameter bytes must not be null.");
        }
        if (index < 0) {
            throw new IllegalArgumentException("parameter index must be great than equal to 0.");
        }
        if (length < 1) {
            throw new IllegalArgumentException("parameter length must be great than equal to 1.");
        }

        int preIndex = index - 1;
        int endIndex = index + length;
        if (endIndex > bytes.length) {
            throw new IllegalArgumentException("out of range (index + length > bytes.length).");
        }

        long value = 0;

        for (int i = endIndex - 1; i > preIndex; i--) {
            value <<= 8;
            value |= (bytes[i] & 0xFF);
        }

        return value;
    }
}
